/*semexample.c  通过信号量实现父子进程之间执行顺序的控制*/
#include "semlib.h"  // 引入自定义的信号量操作函数库头文件

// 主函数，程序的入口点
int main(void)
{
    pid_t result;  // 用于存储 fork 函数的返回值，以此判断是父进程还是子进程
    int sem_id;    // 信号量的标识符

    /*
     * 获取信号量的标识符，使用 ftok 函数生成一个键值。
     * ftok 函数通过当前目录（"."）和字符 'a' 生成一个唯一的键值。
     * 0666 表示权限，IPC_CREAT 表示如果信号量不存在则创建。
     */
    sem_id = semget(ftok(".", 'a'), 1, 0666 | IPC_CREAT);

    // 调用自定义的 init_sem 函数初始化信号量，将其初始值设为 0
    init_sem(sem_id, 0);

    // 创建一个子进程
    result = fork();

    // 检查 fork 是否失败
    if (result == -1)
    {
        // 若失败，输出错误信息
        perror("Fork failed\n");
    }
    // 子进程执行的代码
    else if (result == 0)
    {
        // 子进程休眠一段时间，模拟一些耗时操作
        sleep(DELAY_TIME);

        // 输出子进程的信息
        printf("The child progress output\n");
        printf("BBBBBBBBBBBB\n");

        // 调用自定义的 sem_v 函数执行 V 操作，释放信号量
        sem_v(sem_id);
    }
    // 父进程执行的代码
    else
    {
        // 调用自定义的 sem_p 函数执行 P 操作，等待信号量
        sem_p(sem_id);

        // 输出父进程的信息
        printf("The father process output \n");
        printf("AAAAAAAAAAA\n");

        // 调用自定义的 del_sem 函数删除信号量
        del_sem(sem_id);
    }

    // 程序正常退出
    exit(0);
}